from chat.model.Action import Action
from chat.model.Channel import Channel
from chat.model.User import User

from ActionBase import ActionBase
from ActionExceptions import ActionIntegrityException
from Response import Response


class ActionJoin(ActionBase):
    _action_token = 'join'
    
    _TARGET_KEY = 'target'

    _ERROR_ALREADY_JOINED   = 0x0001
    _ERROR_NO_TARGET        = 0x0002

    def handle(self, postData):
        response = Response()
        actionTarget = postData.get(self._TARGET_KEY, None)

        actionUser = User.verify_message(postData.get(self._USER_ID_TOKEN, None), postData.get(self._MESSAGE_KEY_TOKEN, None), postData.get(self._MESSAGE_HASH_TOKEN, None))
        if actionUser is None:
            raise ActionIntegrityException()

        if actionTarget is None or len(actionTarget) == 0:
            response._status = self._ERROR_NO_TARGET
            response._errors.append("No channel name specified.")
            return response

        channel = None
        try:
            channel = Channel.objects.get(name=actionTarget)

            if channel in actionUser.channels.all():
                response._status = self._ERROR_ALREADY_JOINED
                response._errors.append("Already in channel %s." % actionTarget)
                return response
        except Channel.DoesNotExist:
            channel = Channel()
            channel.name = actionTarget
            channel.save()
        
        actionUser.channels.add(channel)
        
        self._log_action(actionUser, channel);
        
        response._data = {'target_name':actionTarget, 'target_key':channel.hash, 'target_users':dict([[x.username, x.identity_id] for x in ActionJoin.get_users(channel)])}
        return response
    
    def _log_action(self, user, target):
        action = Action()
        action.action = 'JOIN'
        action.username = user.username
        action.username_id = user.identity_id
        action.target = target
        action.save()
        
    @classmethod
    def get_users(cls, target):
        return User.objects.\
                filter(channels__hash=target.hash).\
                order_by('username')